﻿///////////////////////////////////////////////////////////////////////////////
//
//  This file is part of MathLib.NET.
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//  
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//  
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library;  If not, see 
//  <http://www.gnu.org/licenses/>.
//
///////////////////////////////////////////////////////////////////////////////

using System;
using ILNumerics;

namespace MathLib
{
    /// <summary>
    /// Complex calculator type.
    /// </summary>
    struct MLComplex : INumber<complex>
    {
        public complex Add(complex op1, complex op2)
        {
            return op1 + op2;
        }

        public complex Sub(complex op1, complex op2)
        {
            return op1 - op2;
        }

        public complex Mul(complex op1, complex op2)
        {
            return op1 * op2;
        }

        public complex Div(complex op1, complex op2)
        {
            return op1 / op2;
        }

        public complex Pow(complex op1, complex op2)
        {
            return complex.Pow(op1, op2);
        }

        public complex Neg(complex op1)
        {
            return -op1;
        }

        public complex Abs(complex a)
        {
            return complex.Abs(a);
        }

        public bool Lt(complex a, complex b)
        {
            return a < b;
        }

        public bool Gt(complex a, complex b)
        {
            return a > b;
        }

        public bool Le(complex a, complex b)
        {
            return a <= b;
        }

        public bool Ge(complex a, complex b)
        {
            return a >= b;
        }

        public bool Eq(complex a, complex b)
        {
            return a == b;
        }

        public bool Ne(complex a, complex b)
        {
            return a != b;
        }

        public complex FromComplex(complex a)
        {
            return a;
        }

        public complex FromFComplex(fcomplex a)
        {
            return a;
        }

        public complex FromDouble(double a)
        {
            return a;
        }

        public complex FromFloat(float a)
        {
            return a;
        }

        public complex FromInt(int a)
        {
            return a;
        }

        public complex FromUInt(uint a)
        {
            return a;
        }
    }

    /// <summary>
    /// Complex calculator type.
    /// </summary>
    struct MLFComplex : INumber<fcomplex>
    {
        public fcomplex Add(fcomplex op1, fcomplex op2)
        {
            return op1 + op2;
        }

        public fcomplex Sub(fcomplex op1, fcomplex op2)
        {
            return op1 - op2;
        }

        public fcomplex Mul(fcomplex op1, fcomplex op2)
        {
            return op1 * op2;
        }

        public fcomplex Div(fcomplex op1, fcomplex op2)
        {
            return op1 / op2;
        }

        public fcomplex Pow(fcomplex op1, fcomplex op2)
        {
            return fcomplex.Pow(op1, op2);
        }

        public fcomplex Neg(fcomplex op1)
        {
            return -op1;
        }

        public fcomplex Abs(fcomplex a)
        {
            return fcomplex.Abs(a);
        }

        public bool Lt(fcomplex a, fcomplex b)
        {
            return a < b;
        }

        public bool Gt(fcomplex a, fcomplex b)
        {
            return a > b;
        }

        public bool Le(fcomplex a, fcomplex b)
        {
            return a <= b;
        }

        public bool Ge(fcomplex a, fcomplex b)
        {
            return a >= b;
        }

        public bool Eq(fcomplex a, fcomplex b)
        {
            return a == b;
        }

        public bool Ne(fcomplex a, fcomplex b)
        {
            return a != b;
        }

        public fcomplex FromComplex(complex a)
        {
            return new fcomplex((float)a.real, (float)a.imag);
        }

        public fcomplex FromFComplex(fcomplex a)
        {
            return a;
        }

        public fcomplex FromDouble(double a)
        {
            return a;
        }

        public fcomplex FromFloat(float a)
        {
            return a;
        }

        public fcomplex FromInt(int a)
        {
            return a;
        }

        public fcomplex FromUInt(uint a)
        {
            return a;
        }
    }

    /// <summary>
    /// Double calculator type.
    /// </summary>
    struct MLDouble : INumber<double>
    {
        public double Add(double op1, double op2)
        {
            return op1 + op2;
        }

        public double Sub(double op1, double op2)
        {
            return op1 - op2;
        }

        public double Mul(double op1, double op2)
        {
            return op1 * op2;
        }

        public double Div(double op1, double op2)
        {
            return op1 / op2;
        }

        public double Pow(double op1, double op2)
        {
            return Math.Pow(op1, op2);
        }

        public double Neg(double op1)
        {
            return -op1;
        }

        public double Abs(double a)
        {
            return Math.Abs(a);
        }

        public bool Lt(double a, double b)
        {
            return a < b;
        }

        public bool Gt(double a, double b)
        {
            return a > b;
        }

        public bool Le(double a, double b)
        {
            return a <= b;
        }

        public bool Ge(double a, double b)
        {
            return a >= b;
        }

        public bool Eq(double a, double b)
        {
            return a == b;
        }

        public bool Ne(double a, double b)
        {
            return a != b;
        }

        public double FromComplex(complex a)
        {
            return a.real;
        }

        public double FromFComplex(fcomplex a)
        {
            return a.real;
        }

        public double FromDouble(double a)
        {
            return a;
        }

        public double FromFloat(float a)
        {
            return a;
        }

        public double FromInt(int a)
        {
            return a;
        }

        public double FromUInt(uint a)
        {
            return a;
        }
    }

    /// <summary>
    /// Float calculator type.
    /// </summary>
    struct MLFloat : INumber<float>
    {
        public float Add(float op1, float op2)
        {
            return op1 + op2;
        }

        public float Sub(float op1, float op2)
        {
            return op1 - op2;
        }

        public float Mul(float op1, float op2)
        {
            return op1 * op2;
        }

        public float Div(float op1, float op2)
        {
            return op1 / op2;
        }

        public float Pow(float op1, float op2)
        {
            return (float)Math.Pow(op1, op2);
        }

        public float Neg(float op1)
        {
            return -op1;
        }

        public float Abs(float a)
        {
            return Math.Abs(a);
        }

        public bool Lt(float a, float b)
        {
            return a < b;
        }

        public bool Gt(float a, float b)
        {
            return a > b;
        }

        public bool Le(float a, float b)
        {
            return a <= b;
        }

        public bool Ge(float a, float b)
        {
            return a >= b;
        }

        public bool Eq(float a, float b)
        {
            return a == b;
        }

        public bool Ne(float a, float b)
        {
            return a != b;
        }

        public float FromComplex(complex a)
        {
            return (float)a.real;
        }

        public float FromFComplex(fcomplex a)
        {
            return a.real;
        }

        public float FromDouble(double a)
        {
            return (float)a;
        }

        public float FromFloat(float a)
        {
            return a;
        }

        public float FromInt(int a)
        {
            return a;
        }

        public float FromUInt(uint a)
        {
            return a;
        }
    }
}
